#include "timebase_10k.h"



extern uint8_t g_mods_timeout;


SOFTTIME_LIST_T timer_list[MAX_ST_NUM]=
{
 {.ST_num=1,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
 {.ST_num=2,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
 {.ST_num=3,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
 {.ST_num=4,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
 {.ST_num=5,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
 {.ST_num=6,.Count=0,.mode=MODE_ONCE,.state=CYCLE_STOP,.timeOutSetVal=1000,.flag=1},
};

void ST_setTimerTimeOut(uint8_t ST_Num,uint32_t outTime)
{
    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            timer_list[i].timeOutSetVal=outTime;
        }
    }
}

bool ST_checkTimerFlag(uint8_t ST_Num)
{
    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            return timer_list[i].flag;
        }
    }
}

void ST_reloadTimer(uint8_t ST_Num)
{

    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            timer_list[i].flag=0;
            timer_list[i].Count=timer_list[i].timeOutSetVal;
        }
    }
}

void ST_stopTimer(uint8_t ST_Num)
{
    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            timer_list[i].state=CYCLE_STOP;
        }
    }
}

void ST_startTimer(uint8_t ST_Num)
{
    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            timer_list[i].state=CYCLE_READY;
        }
    }
}

void ST_setTimerMode(uint8_t ST_Num,CounterMode_E mode)
{
    int i=0;
    for(i=0;i<MAX_ST_NUM;i++)
    {
        if(ST_Num==timer_list[i].ST_num)
        {
            timer_list[i].mode=mode;
        }
    }
}

void timebase_cupTim0Init(void)
{
    Interrupt_register(INT_TIMER0, &cpuTimer0ISR);

    initCPUTimers();

    configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1);
    CPUTimer_enableInterrupt(CPUTIMER0_BASE);

    Interrupt_enable(INT_TIMER0);

    CPUTimer_startTimer(CPUTIMER0_BASE);
    EINT;
    ERTM;
}

void initCPUTimers(void)
{
    //
    // Initialize timer period to maximum
    //
    CPUTimer_setPeriod(CPUTIMER0_BASE, TIM0_PERIOD);



    //
    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    //
    CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);


    //
    // Make sure timer is stopped
    //
    CPUTimer_stopTimer(CPUTIMER0_BASE);


    //
    // Reload all counter register with period value
    //
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);

}

void configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
    uint32_t temp;

    //
    // Initialize timer period:
    //
    temp = (uint32_t)(freq / 10000 * period);
    CPUTimer_setPeriod(cpuTimer, temp);

    //
    // Set pre-scale counter to divide by 1 (SYSCLKOUT):
    //
    CPUTimer_setPreScaler(cpuTimer, 0);

    //
    // Initializes timer control register. The timer is stopped, reloaded,
    // free run disabled, and interrupt enabled.
    // Additionally, the free and soft bits are set
    //
    CPUTimer_stopTimer(cpuTimer);
    CPUTimer_reloadTimerCounter(cpuTimer);
    CPUTimer_setEmulationMode(cpuTimer,
                              CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(cpuTimer);

}



__interrupt void  cpuTimer0ISR(void)
{
    int i = 0;
    for (i = 0; i < MAX_ST_NUM; i++)
    {

        switch (timer_list[i].state)
        {
            case CYCLE_END:
                if(timer_list[i].flag!=1)
                {
                    if(timer_list[i].mode==MODE_ONCE)
                    {
                        timer_list[i].state=CYCLE_STOP;
                    }
                    else
                    {
                        timer_list[i].state=CYCLE_READY;
                    }
                }
            case CYCLE_READY:
                if(timer_list[i].timeOutSetVal!=1)
                {
                    timer_list[i].Count=timer_list[i].timeOutSetVal;
                    timer_list[i].Count--;
                    timer_list[i].state = CYCLE_RUNNING;
                }
                else
                {
                    timer_list[i].Count=0;
                    timer_list[i].flag=1;
                    timer_list[i].state=CYCLE_END;
                }

                break;

            case CYCLE_RUNNING:
                if(--timer_list[i].Count==0)
                {
                    timer_list[i].state=CYCLE_END;
                    timer_list[i].flag=1;
                }
                break;

            case CYCLE_STOP:

                break;

            default:

                break;
        }
    }

    //
    // Acknowledge this interrupt to receive more interrupts from group 1
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}


__interrupt void cpuTimer2ISR(void)
{
    g_mods_timeout=1;
}



